#include "device/ec200/AtNetworkHttpEC200.h"

#define HTTP_BASE_CONNECT "CONNECT\r\n" // 待发送数据状态位

#define HTTP_BASE_HEADER_0 "AT+QHTTPCFG=\"contextid\",1"      // 配置请求参数
#define HTTP_BASE_HEADER_1 "AT+QHTTPCFG=\"responseheader\",0" // 配置请求参数

#define HTTP_BASE_SEND_URL "AT+QHTTPURL=%d,80\r\n" // 发送URL
#define HTTP_BASE_READ_CMD "AT+QHTTPREAD=80"       // 开始读取数据指令

#define HTTP_GET_LENGTH "+QHTTPGET: 0,200," // GET请求内容长度返回
#define HTTP_GET_START_REQ "AT+QHTTPGET=80" // 发起GET请求

#define HTTP_POST_LENGTH "+QHTTPPOST: 0,200,"           // POST请求内容长度返回
#define HTTP_POST_START_REQ "AT+QHTTPPOST=%d,60,80\r\n" // 发起POST请求

/**
 * 发起GET请求
 */
size_t AtNetworkHttpEC200::get(HttpCallback fun, char *url, uint32_t timeout) {
  if (fun != nullptr && this->executeRequest(fun, url) == AT_RCODE1) {
    this->device->streamWriteClear(HTTP_GET_START_REQ GSM_NL);

    if (this->wait(90000, HTTP_GET_LENGTH) == AT_RCODE1) {
      return this->executeResponse(fun, url);
    }
  }

  return CONNECT_ERR_0;
}

/**
 * 发起POST请求
 */
size_t AtNetworkHttpEC200::post(HttpCallback fun, char *url, char *body, uint32_t timeout) {
  if (fun != nullptr && this->executeRequest(fun, url) == AT_RCODE1) {
    this->device->streamPrintfClear(HTTP_POST_START_REQ, strlen(body));
    if (this->wait(90000, HTTP_BASE_CONNECT) == AT_RCODE1) {
      this->device->streamWriteClear(body, GSM_NL);
    } else {
      return CONNECT_ERR_0;
    }

    if (this->wait(30000, HTTP_POST_LENGTH) == AT_RCODE1) {
      return this->executeResponse(fun, url);
    }
  }

  return CONNECT_ERR_0;
}

size_t AtNetworkHttpEC200::executeResponse(HttpCallback fun, char *url) {
  // -------------------------------------------------------------------
  // 发送读取响应内容指令
  // -------------------------------------------------------------------
  size_t contentLength = this->device->streamGetInt(16, '\n');
  this->device->streamWriteClear(HTTP_BASE_READ_CMD GSM_NL);
  if (this->wait(90000, HTTP_BASE_CONNECT) != AT_RCODE1) {
    return CONNECT_ERR_0;
  }

  // -------------------------------------------------------------------
  // 读取全部响应内容
  // -------------------------------------------------------------------
  char *contentBody = (char *)MEM_ALLOC(contentLength + 1);
  for (size_t idx = 0; idx < contentLength; idx++) {
    while (!this->device->_stream->available()) {
      AT_YIELD();
    }

    contentBody[idx] = this->device->_stream->read();
    contentBody[idx + 1] = '\0';

    AT_YIELD();
  }

  // -------------------------------------------------------------------
  // 响应内容回调
  // -------------------------------------------------------------------
  size_t res = fun(contentLength, contentBody);

  free(contentBody);

  return res;
}

size_t AtNetworkHttpEC200::executeRequest(HttpCallback fun, char *url) {
  this->device->streamWriteClear(HTTP_BASE_HEADER_0 GSM_NL);
  if (this->device->wait(AT_OK) != AT_RCODE1) {
    return CONNECT_ERR_0;
  }
  this->device->streamWriteClear(HTTP_BASE_HEADER_1 GSM_NL);
  if (this->device->wait(AT_OK) != AT_RCODE1) {
    return CONNECT_ERR_0;
  }

  // -------------------------------------------------------------------
  // 发送HTTP请求的URL
  // -------------------------------------------------------------------
  this->device->streamPrintfClear(HTTP_BASE_SEND_URL, strlen(url));
  if (this->wait(30000, HTTP_BASE_CONNECT) == AT_RCODE1) {
    this->device->streamWriteClear(url, GSM_NL);
  } else {
    return CONNECT_ERR_0;
  }

  return this->device->wait(AT_OK);
}
